home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / WarpQuake / Src / r_aclip.c < prev    next >
C/C++ Source or Header  |  2000-05-22  |  9KB  |  351 lines

  1. /*
  2. Copyright (C) 1996-1997 Id Software, Inc.
  3.  
  4. This program is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU General Public License
  6. as published by the Free Software Foundation; either version 2
  7. of the License, or (at your option) any later version.
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
  12.  
  13. See the GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  18.  
  19. */
  20. // r_aclip.c: clip routines for drawing Alias models directly to the screen
  21.  
  22. #include "quakedef.h"
  23. #include "r_local.h"
  24. #include "d_local.h"
  25.  
  26. static finalvert_t        fv[2][8];
  27. static auxvert_t        av[8];
  28.  
  29. void R_AliasProjectFinalVert (finalvert_t *fv, auxvert_t *av);
  30. void R_Alias_clip_top (finalvert_t *pfv0, finalvert_t *pfv1,
  31.     finalvert_t *out);
  32. void R_Alias_clip_bottom (finalvert_t *pfv0, finalvert_t *pfv1,
  33.     finalvert_t *out);
  34. void R_Alias_clip_left (finalvert_t *pfv0, finalvert_t *pfv1,
  35.     finalvert_t *out);
  36. void R_Alias_clip_right (finalvert_t *pfv0, finalvert_t *pfv1,
  37.     finalvert_t *out);
  38.  
  39.  
  40. /*
  41. ================
  42. R_Alias_clip_z
  43.  
  44. pfv0 is the unclipped vertex, pfv1 is the z-clipped vertex
  45. ================
  46. */
  47. void R_Alias_clip_z (finalvert_t *pfv0, finalvert_t *pfv1, finalvert_t *out)
  48. {
  49.     float        scale;
  50.     auxvert_t    *pav0, *pav1, avout;
  51.  
  52.     pav0 = &av[pfv0 - &fv[0][0]];
  53.     pav1 = &av[pfv1 - &fv[0][0]];
  54.  
  55.     if (pfv0->v[1] >= pfv1->v[1])
  56.     {
  57.         scale = (ALIAS_Z_CLIP_PLANE - pav0->fv[2]) /
  58.                 (pav1->fv[2] - pav0->fv[2]);
  59.     
  60.         avout.fv[0] = pav0->fv[0] + (pav1->fv[0] - pav0->fv[0]) * scale;
  61.         avout.fv[1] = pav0->fv[1] + (pav1->fv[1] - pav0->fv[1]) * scale;
  62.         avout.fv[2] = ALIAS_Z_CLIP_PLANE;
  63.     
  64.         out->v[2] =    pfv0->v[2] + (pfv1->v[2] - pfv0->v[2]) * scale;
  65.         out->v[3] =    pfv0->v[3] + (pfv1->v[3] - pfv0->v[3]) * scale;
  66.         out->v[4] =    pfv0->v[4] + (pfv1->v[4] - pfv0->v[4]) * scale;
  67.     }
  68.     else
  69.     {
  70.         scale = (ALIAS_Z_CLIP_PLANE - pav1->fv[2]) /
  71.                 (pav0->fv[2] - pav1->fv[2]);
  72.     
  73.         avout.fv[0] = pav1->fv[0] + (pav0->fv[0] - pav1->fv[0]) * scale;
  74.         avout.fv[1] = pav1->fv[1] + (pav0->fv[1] - pav1->fv[1]) * scale;
  75.         avout.fv[2] = ALIAS_Z_CLIP_PLANE;
  76.     
  77.         out->v[2] =    pfv1->v[2] + (pfv0->v[2] - pfv1->v[2]) * scale;
  78.         out->v[3] =    pfv1->v[3] + (pfv0->v[3] - pfv1->v[3]) * scale;
  79.         out->v[4] =    pfv1->v[4] + (pfv0->v[4] - pfv1->v[4]) * scale;
  80.     }
  81.  
  82.     R_AliasProjectFinalVert (out, &avout);
  83.  
  84.     if (out->v[0] < r_refdef.aliasvrect.x)
  85.         out->flags |= ALIAS_LEFT_CLIP;
  86.     if (out->v[1] < r_refdef.aliasvrect.y)
  87.         out->flags |= ALIAS_TOP_CLIP;
  88.     if (out->v[0] > r_refdef.aliasvrectright)
  89.         out->flags |= ALIAS_RIGHT_CLIP;
  90.     if (out->v[1] > r_refdef.aliasvrectbottom)
  91.         out->flags |= ALIAS_BOTTOM_CLIP;    
  92. }
  93.  
  94.  
  95. #if    !id386
  96.  
  97. void R_Alias_clip_left (finalvert_t *pfv0, finalvert_t *pfv1, finalvert_t *out)
  98. {
  99.     float        scale;
  100.     int            i;
  101.  
  102.     if (pfv0->v[1] >= pfv1->v[1])
  103.     {
  104.         scale = (float)(r_refdef.aliasvrect.x - pfv0->v[0]) /
  105.                 (pfv1->v[0] - pfv0->v[0]);
  106.         for (i=0 ; i<6 ; i++)
  107.             out->v[i] = pfv0->v[i] + (pfv1->v[i] - pfv0->v[i])*scale + 0.5;
  108.     }
  109.     else
  110.     {
  111.         scale = (float)(r_refdef.aliasvrect.x - pfv1->v[0]) /
  112.                 (pfv0->v[0] - pfv1->v[0]);
  113.         for (i=0 ; i<6 ; i++)
  114.             out->v[i] = pfv1->v[i] + (pfv0->v[i] - pfv1->v[i])*scale + 0.5;
  115.     }
  116. }
  117.  
  118.  
  119. void R_Alias_clip_right (finalvert_t *pfv0, finalvert_t *pfv1,
  120.     finalvert_t *out)
  121. {
  122.     float        scale;
  123.     int            i;
  124.  
  125.     if (pfv0->v[1] >= pfv1->v[1])
  126.     {
  127.         scale = (float)(r_refdef.aliasvrectright - pfv0->v[0]) /
  128.                 (pfv1->v[0] - pfv0->v[0]);
  129.         for (i=0 ; i<6 ; i++)
  130.             out->v[i] = pfv0->v[i] + (pfv1->v[i] - pfv0->v[i])*scale + 0.5;
  131.     }
  132.     else
  133.     {
  134.         scale = (float)(r_refdef.aliasvrectright - pfv1->v[0]) /
  135.                 (pfv0->v[0] - pfv1->v[0]);
  136.         for (i=0 ; i<6 ; i++)
  137.             out->v[i] = pfv1->v[i] + (pfv0->v[i] - pfv1->v[i])*scale + 0.5;
  138.     }
  139. }
  140.  
  141.  
  142. void R_Alias_clip_top (finalvert_t *pfv0, finalvert_t *pfv1, finalvert_t *out)
  143. {
  144.     float        scale;
  145.     int            i;
  146.  
  147.     if (pfv0->v[1] >= pfv1->v[1])
  148.     {
  149.         scale = (float)(r_refdef.aliasvrect.y - pfv0->v[1]) /
  150.                 (pfv1->v[1] - pfv0->v[1]);
  151.         for (i=0 ; i<6 ; i++)
  152.             out->v[i] = pfv0->v[i] + (pfv1->v[i] - pfv0->v[i])*scale + 0.5;
  153.     }
  154.     else
  155.     {
  156.         scale = (float)(r_refdef.aliasvrect.y - pfv1->v[1]) /
  157.                 (pfv0->v[1] - pfv1->v[1]);
  158.         for (i=0 ; i<6 ; i++)
  159.             out->v[i] = pfv1->v[i] + (pfv0->v[i] - pfv1->v[i])*scale + 0.5;
  160.     }
  161. }
  162.  
  163.  
  164. void R_Alias_clip_bottom (finalvert_t *pfv0, finalvert_t *pfv1,
  165.     finalvert_t *out)
  166. {
  167.     float        scale;
  168.     int            i;
  169.  
  170.     if (pfv0->v[1] >= pfv1->v[1])
  171.     {
  172.         scale = (float)(r_refdef.aliasvrectbottom - pfv0->v[1]) /
  173.                 (pfv1->v[1] - pfv0->v[1]);
  174.  
  175.         for (i=0 ; i<6 ; i++)
  176.             out->v[i] = pfv0->v[i] + (pfv1->v[i] - pfv0->v[i])*scale + 0.5;
  177.     }
  178.     else
  179.     {
  180.         scale = (float)(r_refdef.aliasvrectbottom - pfv1->v[1]) /
  181.                 (pfv0->v[1] - pfv1->v[1]);
  182.  
  183.         for (i=0 ; i<6 ; i++)
  184.             out->v[i] = pfv1->v[i] + (pfv0->v[i] - pfv1->v[i])*scale + 0.5;
  185.     }
  186. }
  187.  
  188. #endif
  189.  
  190.  
  191. int R_AliasClip (finalvert_t *in, finalvert_t *out, int flag, int count,
  192.     void(*clip)(finalvert_t *pfv0, finalvert_t *pfv1, finalvert_t *out) )
  193. {
  194.     int            i,j,k;
  195.     int            flags, oldflags;
  196.     
  197.     j = count-1;
  198.     k = 0;
  199.     for (i=0 ; i<count ; j = i, i++)
  200.     {
  201.         oldflags = in[j].flags & flag;
  202.         flags = in[i].flags & flag;
  203.  
  204.         if (flags && oldflags)
  205.             continue;
  206.         if (oldflags ^ flags)
  207.         {
  208.             clip (&in[j], &in[i], &out[k]);
  209.             out[k].flags = 0;
  210.             if (out[k].v[0] < r_refdef.aliasvrect.x)
  211.                 out[k].flags |= ALIAS_LEFT_CLIP;
  212.             if (out[k].v[1] < r_refdef.aliasvrect.y)
  213.                 out[k].flags |= ALIAS_TOP_CLIP;
  214.             if (out[k].v[0] > r_refdef.aliasvrectright)
  215.                 out[k].flags |= ALIAS_RIGHT_CLIP;
  216.             if (out[k].v[1] > r_refdef.aliasvrectbottom)
  217.                 out[k].flags |= ALIAS_BOTTOM_CLIP;    
  218.             k++;
  219.         }
  220.         if (!flags)
  221.         {
  222.             out[k] = in[i];
  223.             k++;
  224.         }
  225.     }
  226.     
  227.     return k;
  228. }
  229.  
  230.  
  231. /*
  232. ================
  233. R_AliasClipTriangle
  234. ================
  235. */
  236. void R_AliasClipTriangle (mtriangle_t *ptri)
  237. {
  238.     int                i, k, pingpong;
  239.     mtriangle_t        mtri;
  240.     unsigned        clipflags;
  241.  
  242. // copy vertexes and fix seam texture coordinates
  243.     if (ptri->facesfront)
  244.     {
  245.         fv[0][0] = pfinalverts[ptri->vertindex[0]];
  246.         fv[0][1] = pfinalverts[ptri->vertindex[1]];
  247.         fv[0][2] = pfinalverts[ptri->vertindex[2]];
  248.     }
  249.     else
  250.     {
  251.         for (i=0 ; i<3 ; i++)
  252.         {
  253.             fv[0][i] = pfinalverts[ptri->vertindex[i]];
  254.     
  255.             if (!ptri->facesfront && (fv[0][i].flags & ALIAS_ONSEAM) )
  256.                 fv[0][i].v[2] += r_affinetridesc.seamfixupX16;
  257.         }
  258.     }
  259.  
  260. // clip
  261.     clipflags = fv[0][0].flags | fv[0][1].flags | fv[0][2].flags;
  262.  
  263.     if (clipflags & ALIAS_Z_CLIP)
  264.     {
  265.         for (i=0 ; i<3 ; i++)
  266.             av[i] = pauxverts[ptri->vertindex[i]];
  267.  
  268.         k = R_AliasClip (fv[0], fv[1], ALIAS_Z_CLIP, 3, R_Alias_clip_z);
  269.         if (k == 0)
  270.             return;
  271.  
  272.         pingpong = 1;
  273.         clipflags = fv[1][0].flags | fv[1][1].flags | fv[1][2].flags;
  274.     }
  275.     else
  276.     {
  277.         pingpong = 0;
  278.         k = 3;
  279.     }
  280.  
  281.     if (clipflags & ALIAS_LEFT_CLIP)
  282.     {
  283.         k = R_AliasClip (fv[pingpong], fv[pingpong ^ 1],
  284.                             ALIAS_LEFT_CLIP, k, R_Alias_clip_left);
  285.         if (k == 0)
  286.             return;
  287.  
  288.         pingpong ^= 1;
  289.     }
  290.  
  291.     if (clipflags & ALIAS_RIGHT_CLIP)
  292.     {
  293.         k = R_AliasClip (fv[pingpong], fv[pingpong ^ 1],
  294.                             ALIAS_RIGHT_CLIP, k, R_Alias_clip_right);
  295.         if (k == 0)
  296.             return;
  297.  
  298.         pingpong ^= 1;
  299.     }
  300.  
  301.     if (clipflags & ALIAS_BOTTOM_CLIP)
  302.     {
  303.         k = R_AliasClip (fv[pingpong], fv[pingpong ^ 1],
  304.                             ALIAS_BOTTOM_CLIP, k, R_Alias_clip_bottom);
  305.         if (k == 0)
  306.             return;
  307.  
  308.         pingpong ^= 1;
  309.     }
  310.  
  311.     if (clipflags & ALIAS_TOP_CLIP)
  312.     {
  313.         k = R_AliasClip (fv[pingpong], fv[pingpong ^ 1],
  314.                             ALIAS_TOP_CLIP, k, R_Alias_clip_top);
  315.         if (k == 0)
  316.             return;
  317.  
  318.         pingpong ^= 1;
  319.     }
  320.  
  321.     for (i=0 ; i<k ; i++)
  322.     {
  323.         if (fv[pingpong][i].v[0] < r_refdef.aliasvrect.x)
  324.             fv[pingpong][i].v[0] = r_refdef.aliasvrect.x;
  325.         else if (fv[pingpong][i].v[0] > r_refdef.aliasvrectright)
  326.             fv[pingpong][i].v[0] = r_refdef.aliasvrectright;
  327.  
  328.         if (fv[pingpong][i].v[1] < r_refdef.aliasvrect.y)
  329.             fv[pingpong][i].v[1] = r_refdef.aliasvrect.y;
  330.         else if (fv[pingpong][i].v[1] > r_refdef.aliasvrectbottom)
  331.             fv[pingpong][i].v[1] = r_refdef.aliasvrectbottom;
  332.  
  333.         fv[pingpong][i].flags = 0;
  334.     }
  335.  
  336. // draw triangles
  337.     mtri.facesfront = ptri->facesfront;
  338.     r_affinetridesc.ptriangles = &mtri;
  339.     r_affinetridesc.pfinalverts = fv[pingpong];
  340.  
  341. // FIXME: do all at once as trifan?
  342.     mtri.vertindex[0] = 0;
  343.     for (i=1 ; i<k-1 ; i++)
  344.     {
  345.         mtri.vertindex[1] = i;
  346.         mtri.vertindex[2] = i+1;
  347.         D_PolysetDraw ();
  348.     }
  349. }
  350.  
  351.